package com.su.lightthings.service

import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import com.jeremyliao.liveeventbus.LiveEventBus
import com.su.lightthings.bean.AlarmBean
import com.su.lightthings.bean.BaseDataBean
import com.su.lightthings.bean.GpsBean
import com.su.lightthings.bean.ReceiveDataBean
import com.su.lightthings.bean.SportDataBean
import com.su.lightthings.bean.TaskEventBean
import com.su.lightthings.utils.ByteUtils
import com.su.lightthings.utils.Cons
import com.su.lightthings.utils.getIndexToLong
import com.su.lightthings.utils.toInt
import com.su.lightthings.utils.toLong
import com.su.lightthings.utils.toUShort
import com.su.lightthings.viewmodel.CommonViewModel

/**
 * 手表到App 数据解析类
 */
object DataAnalysis {
    private const val TAG = "DataAnalysis"
    private const val PACKAGE_DATA_TIME_OUT = 500

    //组合协议的Map
    private val functionMap = hashMapOf<UShort, ByteArray>()

    //处理组合协议异常的Handler
    private val mFunctionHandler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            Log.d(TAG, "收到组包清除信息: ${msg.what}")
            functionMap.remove(msg.what.toUShort())
        }
    }

    fun analysisReceiveData(data: ByteArray): ReceiveDataBean {

        val currFrame = data.toInt(
            Cons.ProtocolIndex.CURRENT_FRAME_INDEX, Cons.ProtocolIndex.CURRENT_FRAME_SIZE
        )
        val totalFrame =
            data.toInt(Cons.ProtocolIndex.TOTAL_FRAME_INDEX, Cons.ProtocolIndex.TOTAL_FRAME_SIZE)

        val functionFlag = data.toInt(
            Cons.ProtocolIndex.FUNCTION_FLAG_INDEX, Cons.ProtocolIndex.FUNCTION_FLAG_SIZE
        )

        val checkSum =
            data.toUShort(Cons.ProtocolIndex.CHECK_SUM_INDEX, Cons.ProtocolIndex.CHECK_SUM_SIZE)

        val packageLength = data.toUShort(
            Cons.ProtocolIndex.PACKAGE_LENGTH_INDEX, Cons.ProtocolIndex.PACKAGE_LENGTH_SIZE
        )

        val functionId =
            data.toUShort(Cons.ProtocolIndex.FUNCTION_ID_INDEX, Cons.ProtocolIndex.FUNCTION_ID_SIZE)

        val dataLength =
            data.toUShort(Cons.ProtocolIndex.DATA_LENGTH_INDEX, Cons.ProtocolIndex.DATA_LENGTH_SIZE)

        val data = copyFrom(data, Cons.ProtocolIndex.DATA_INDEX, dataLength)

        val dataBean = ReceiveDataBean(
            currFrame,
            totalFrame,
            functionFlag,
            checkSum.toInt(),
            packageLength.toInt(),
            functionId.toInt(),
            dataLength.toInt()
        )

        Log.d(TAG, "收到数据: $dataBean")

        when (dataBean.functionId) {

            //region 基础信息类
            //芯片信息
            Cons.BaseFunctionId.CHIP_INFO -> {
                dataBean.setLongData("transMode", data.toLong(0, 1))      //传输方式
                dataBean.setLongData("chipFactory", data.toLong(1, 2))    //芯片厂商
                val chipType = ByteUtils.toString(data.copyOfRange(3, dataLength.toInt() - 3))
                dataBean.setStringData("chipType", chipType)      //芯片型号
            }

            //设备版本号
            Cons.BaseFunctionId.DEVICE_VERSION -> {
                dataBean.setLongData("h1", data.toLong(0, 1))
                dataBean.setLongData("h2", data.toLong(1, 1))
                dataBean.setLongData("s1", data.toLong(2, 1))
                dataBean.setLongData("s2", data.toLong(3, 1))
                dataBean.setLongData("s3", data.toLong(4, 1))
                val model = ByteUtils.toString(data.copyOfRange(5, dataLength.toInt()))
                dataBean.setStringData("model", model)
            }
            //endregion


            //region 绑定信息类
            Cons.BondFunctionId.BIND -> {
                dataBean.setLongData("bind", data.toLong(0, 1))
            }
            //配对请求
            Cons.BondFunctionId.PAIR -> {
                //配对请求
            }
            //功能列表
            Cons.BondFunctionId.FUNCTION_LIST -> {
                dataBean.setLongData("0", data.toLong(0, 1))
                dataBean.setLongData("1", data.toLong(1, 1))
                dataBean.setLongData("2", data.toLong(2, 1))
                dataBean.setLongData("3", data.toLong(3, 1))
                dataBean.setLongData("4", data.toLong(4, 1))
                dataBean.setLongData("5", data.toLong(5, 1))
            }
            //endregion

            //region 设置消息类
            //目标步数
            Cons.SettingFunctionId.STEP_TARGET -> {
                dataBean.setLongData("stepTarget", data.toLong(0, 4))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(3, 1))
            }
            //亮屏时间
            Cons.SettingFunctionId.BRIGHTEN_SCREEN_TIME -> {
                dataBean.setLongData("brightScreenTime", data.toLong(0, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(1, 1))
            }
            //久坐提醒
            Cons.SettingFunctionId.LONG_SIT -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData("duration", data.toLong(5, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))
            }

            //勿扰设置
            Cons.SettingFunctionId.DO_NOT_DISTURB -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(5, 1))
            }

            //震动设置
            Cons.SettingFunctionId.SHAKE -> {
                dataBean.setLongData("level", data.toLong(0, 1))
                dataBean.setLongData("times", data.toLong(1, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(2, 1))
            }

            //抬手亮屏设置
            Cons.SettingFunctionId.HAND_BRIGHTEN_SCREEN -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(5, 1))
            }

            //12/24小时
            Cons.SettingFunctionId.HOUR_TYPE -> {
                dataBean.setLongData("type", data.toLong(0, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(1, 1))
            }

            //语言设置
            Cons.SettingFunctionId.LANGUAGE -> {
                dataBean.setLongData("language", data.toLong(0, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(1, 1))
            }

            //闹钟设置
            Cons.SettingFunctionId.ALARM -> {
                if (dataLength.toInt() <= 2) {
                    //无闹钟
                    return dataBean
                }
                val alarmList = mutableListOf<AlarmBean>()
                val type = data.toInt(0, 1)
                for (i in 0 until (dataLength.toInt() - 1/*增加/删除/修改*/ - 1/*结尾0x00*/) / 5/*5位一个*/) {
                    val id = data.toInt(1 + i.times(5), 1)
                    val switch = data.toInt(2 + i.times(5), 1)
                    val repeat = (data.toInt(3 + i.times(5), 1)) and 1
                    val dayOfWeek = mutableListOf<Int>()
                    for (position in 1..7) {
                        val bit = (data.toInt(3 + i.times(5), 1) ushr position) and 1
                        Log.d(TAG, "闹钟重复日数据解析  >>   position: $position   ===   bit: $bit")
                        dayOfWeek.add(bit)
                    }
                    val hour = data.toInt(4 + i.times(5), 1)
                    val minute = data.toInt(5 + i.times(5), 1)

                    val alarm = AlarmBean(id, type, switch, repeat, dayOfWeek, hour, minute)
                    alarmList.add(alarm)
                }
                dataBean.setAlarmData("alarm", alarmList)
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))

//                dataBean.setLongData("id", data.toLong(1, 1))
//                dataBean.setLongData("switch", data.toLong(2, 1))
//                for (position in 7 downTo 0) {
//                    val bit = (data.toLong(3, 1).toInt() ushr position) and 1
//                    if (position == 0) {
//                        dataBean.setLongData("repeat", bit.toLong())
//                    } else {
//                        dataBean.setLongData("dayOfWeek$position", bit.toLong())
//                    }
//                }
//                dataBean.setLongData("hour", data.toLong(4, 1))
//                dataBean.setLongData("minute", data.toLong(5, 1))
//                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))
            }

            //消息通知开关
            Cons.SettingFunctionId.NOTIFICATION_SWITCH -> {
                //总开关（0：关闭，1：打开）
                val isSwitch = data.toLong(0, 1)
                dataBean.setLongData("notification", isSwitch)
                val appNotifyList = mutableListOf<Int>()

                for (i in 1..4) {
                    val tempList = mutableListOf<Int>()
                    for (position in 0..7) {
                        val bit = (data.toInt(i, 1) ushr position) and 1
                        tempList.add(bit)
                    }
                    appNotifyList.addAll(tempList)
                }
                dataBean.setIntListData("app_notification", appNotifyList)
            }

            //定时心率
            Cons.SettingFunctionId.TIME_HEART -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData("duration", data.toLong(5, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))
            }

            //喝水提醒
            Cons.SettingFunctionId.DRINK_REMIND -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData("duration", data.toLong(5, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))
            }


            //吃药提醒
            Cons.SettingFunctionId.MEDICINE_REMIND -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("hour", data.toLong(1, 1))
                dataBean.setLongData("minute", data.toLong(2, 1))
            }

            //生理期提醒
            Cons.SettingFunctionId.PERIOD -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("year", data.toLong(1, 1))
                dataBean.setLongData("month", data.toLong(2, 1))
                dataBean.setLongData("day", data.toLong(3, 1))
                dataBean.setLongData("duration", data.toLong(4, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(5, 1))
            }

            //定时体温
            Cons.SettingFunctionId.TIMING_BODY_TEMPERATURE -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
                dataBean.setLongData("startHour", data.toLong(1, 1))
                dataBean.setLongData("startMinute", data.toLong(2, 1))
                dataBean.setLongData("endHour", data.toLong(3, 1))
                dataBean.setLongData("endMinute", data.toLong(4, 1))
                dataBean.setLongData("duration", data.toLong(5, 1))
                dataBean.setLongData(Cons.Common.SUCCESS, data.toLong(6, 1))
            }

            //防丢
            Cons.SettingFunctionId.ANTI_LOST -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
            }

            //公英制
            Cons.SettingFunctionId.INCH_TYPE -> {
                dataBean.setLongData("inch", data.toLong(0, 1))
            }

            //天气温度单位
            Cons.SettingFunctionId.TEMPERATURE_TYPE -> {
                dataBean.setLongData("temperatureType", data.toLong(0, 1))
            }

            //SOS
            Cons.SettingFunctionId.SOS -> {
                if (dataLength.toInt() <= 2) {
                    //无SOS联系人
                    return dataBean
                }
                dataBean.setLongData("type", data.toLong(0, 1))
                dataBean.setLongData("id", data.toLong(1, 1))
                val number = ByteUtils.toString(data.copyOfRange(2, 21)).trim()
                val name = ByteUtils.toString(data.copyOfRange(22, dataLength.toInt() - 1)).trim()
                dataBean.setStringData("number", number)
                dataBean.setStringData("name", name)
                dataBean.setLongData("success", data.toLong(dataLength.toInt() - 1, 1))
            }

            //表盘设置

            //手表控制电话
            Cons.SettingFunctionId.PHONE_CONTROL -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
            }

            //找手机
            Cons.SettingFunctionId.FIND_PHONE -> {
                dataBean.setLongData("type", data.toLong(0, 1))
            }

            //找手表


            //拍照控制
            Cons.SettingFunctionId.CAMERA_CONTROL -> {
                dataBean.setLongData("switch", data.toLong(0, 1))
            }
            //用户信息设置
            Cons.SettingFunctionId.USER_INFO -> {
                dataBean.setLongData("system", data.toLong(0, 1))
                dataBean.setLongData("sex", data.toLong(1, 1))
                dataBean.setLongData("age", data.toLong(2, 1))
                dataBean.setLongData("height", data.toLong(3, 2))
                dataBean.setLongData("weight", data.toLong(5, 2))
            }

            //自定义表盘


            //endregion

            //region 数据消息类
            //实时数据
            Cons.DataFunctionId.REAL_TIME_DATA -> {
                //步数数据
                dataBean.setLongData("stepData", data.toLong(0, 4))
                //卡路里（卡）
                dataBean.setLongData("calorie", data.toLong(4, 4))
                //距离（米）
                dataBean.setLongData("distance", data.toLong(8, 4))
                //心率
                dataBean.setLongData("heart", data.toLong(12, 1))
                //电量（百分比）
                dataBean.setLongData("battery", data.toLong(13, 1))
            }
            //运动
            Cons.DataFunctionId.SPORT_RECORDER -> {
                //[54, 59, 01, 01, 80, 0f, e3, 00, 38, 03, 02, 00, 34,
                // 01, 65, 90, 09, cb, 00, 00, 03, c6, 00, 00, 00, 0c, 00, 00, 00, c8, 00, 00, 00, 04, 6e, ff, ff, ff, ff,
                // 01, 65, 90, 09, cb, 00, 00, 03, c6, 00, 00, 00, 0c, 00, 00, 00, c8, 00, 00, 00, 04, 6e, ff, ff, ff, ff]
                if (dataLength.toInt() == 0) return dataBean

                val block = data.size.div(26)
                val dataList = mutableListOf<SportDataBean>()
                for (i in 0 until block) {
                    val type = data.toInt(i * 26 + 0, 1)
                    val startTimeStamp = data.toLong(i * 26 + 1, 4).times(1000)
                        .minus(CommonViewModel.INSTANCE.getTimeZoneRawOffset())
                    val duration = data.toLong(i * 26 + 5, 4)
                    val step = if (data.toLong(
                            i * 26 + 9,
                            4
                        ) == 0xFFFFFFFF
                    ) -1L else data.toLong(i * 26 + 9, 4)
                    val calorie = data.toLong(i * 26 + 13, 4)
                    val distance = if (data.toLong(
                            i * 26 + 17,
                            4
                        ) == 0xFFFFFFFF
                    ) -1L else data.toLong(i * 26 + 17, 4)
                    val heart = data.toInt(i * 26 + 21, 1)
                    val pace = if (data.toLong(i * 26 + 22, 2).toInt() == 0xFFFF) {
                        //不支持
                        "不支持"
                    } else {
                        "${data[22].toInt()}分${data[23].toInt()}秒/公里"
                    }
                    val cadence =
                        if (data.toLong(i * 26 + 24, 2).toInt() == 0xFFFF) -1 else data.toLong(
                            24,
                            2
                        ).toInt()

                    val bean = SportDataBean(
                        type,
                        startTimeStamp,
                        duration,
                        step,
                        calorie,
                        distance,
                        heart,
                        pace,
                        cadence
                    )
                    dataList.add(bean)
                }
                dataBean.setSportDataList(dataList)
            }
            //心率 次/分
            Cons.DataFunctionId.HEART -> {
                Log.d(TAG, "解析心率数据: ${ByteUtils.toHexString(data)}")
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                dataBean.setLongData("heart", data.toLong(4, 1))
                if (dataLength.toInt() == 0) return dataBean

                val block = data.size.div(5)
                val dataList = mutableListOf<BaseDataBean>()
                for (i in 0 until block) {
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.HEART,
                        data.toLong(i * 5 + 0, 4),
                        data.toLong(i * 5 + 4, 1).toInt()
                    )
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("heart", dataList)

                //保存到本地
//                val fullFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
//                val title = fullFormat.format(Date(System.currentTimeMillis()))
//                FileIOUtils.writeFileFromString(CommonViewModel.INSTANCE.heartDirectory, "$title 收到手表心跳消息：\n", true)
//                if (!dataList.isNullOrEmpty()) {
//                    dataList.reverse()
//                    for (baseData in dataList) {
//                        val heartTime = fullFormat.format(baseData.timeStamp.times(1000).minus(CommonViewModel.INSTANCE.getTimeZoneRawOffset()))
//                        val heartContent = baseData.data
//                        FileIOUtils.writeFileFromString(CommonViewModel.INSTANCE.sleepDirectory, "$heartTime  :  $heartContent \n", true)
//                    }
//                }
            }
            //血糖 mmol/l
            Cons.DataFunctionId.BLOOD_GLUCOSE -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                dataBean.setLongData("bloodGlucose", data.toLong(4, 2))
                if (dataLength.toInt() == 0) return dataBean

                val block = data.size.div(6)
                val dataList = mutableListOf<BaseDataBean>()
                for (i in 0 until block) {
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.BLOOD_GLUCOSE,
                        data.toLong(i * 6 + 0, 4),
                        data.toLong(i * 6 + 4, 2).toInt()
                    )
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("bloodGlucose", dataList)
            }
            //血压
            Cons.DataFunctionId.BLOOD_PRESSURE -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                dataBean.setLongData("shuZhangYa", data.toLong(4, 1))
//                dataBean.setLongData("shouSuoYa", data.toLong(5, 1))
                if (dataLength.toInt() == 0) return dataBean

                val block = data.size.div(6)
                val bloodPressureList = mutableListOf<BaseDataBean>()
                for (i in 0 until block) {
                    val shouSuo = data.toInt(i * 6 + 4, 1)
                    val shuZhang = data.toInt(i * 6 + 5, 1)
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.BLOOD_PRESSURE,
                        data.toLong(i * 6 + 0, 4),
                        0
                    )
                    bean.arg1 = shouSuo.toString()
                    bean.arg2 = shuZhang.toString()
                    bloodPressureList.add(bean)
                }
                dataBean.setBaseDataListData("bloodPressure", bloodPressureList)
            }
            //血氧
            Cons.DataFunctionId.BLOOD_OXYGEN -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                dataBean.setLongData("bloodOxygen", data.toLong(4, 1))
                if (dataLength.toInt() == 0) return dataBean

                val block = data.size.div(5)
                val dataList = mutableListOf<BaseDataBean>()
                for (i in 0 until block) {
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.BLOOD_OXYGEN,
                        data.toLong(i * 5 + 0, 4),
                        data.toInt(i * 5 + 4, 1)
                    )
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("bloodOxygen", dataList)
            }
            //睡眠
            Cons.DataFunctionId.SLEEP -> {
                if (dataLength.toInt() == 0) return dataBean

                /* //协议改变(旧)
                val dataList = mutableListOf<BaseDataBean>()
                val block = data.size.div(5)
                for (i in 0 until block) {
                    val bean = BaseDataBean(Cons.DataFunctionId.SLEEP, data.toLong(i * 5 + 0, 4), data.toInt(i * 5 + 4, 1))
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("sleep", dataList)
                */

                //协议改变(新)
                //浅睡眠时间
                val lightSleep = data.toLong(0, 2)
                //深睡眠时间
                val deepSleep = data.toLong(2, 2)
                //快速眼动时间
                val eyeMovements = data.toLong(4, 2)
                //睡眠详细数据
                val dataList = mutableListOf<BaseDataBean>()
                val block = (data.size.minus(6)).div(5)
                for (i in 0 until block) {
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.SLEEP,
                        data.toLong(i * 5 + 6, 4),
                        data.toInt(i * 5 + 10, 1)
                    )
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("sleep", dataList)
                dataBean.setIntListData(
                    "sleepTime",
                    mutableListOf(lightSleep.toInt(), deepSleep.toInt(), eyeMovements.toInt())
                )


                //保存到本地
//                val fullFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
//                val title = fullFormat.format(Date(System.currentTimeMillis()))
//                FileIOUtils.writeFileFromString(CommonViewModel.INSTANCE.sleepDirectory, "$title 收到手表睡眠消息：\n", true)
//                if (!dataList.isNullOrEmpty()) {
//                    dataList.reverse()
//                    for (baseData in dataList) {
//                        val sleepTime = fullFormat.format(baseData.timeStamp.times(1000).minus(CommonViewModel.INSTANCE.getTimeZoneRawOffset()))
//                        val sleepContent = sleepString(baseData.data)
//                        FileIOUtils.writeFileFromString(CommonViewModel.INSTANCE.sleepDirectory, "$sleepTime  :  $sleepContent \n", true)
//                    }
//                }
            }
//HRV
            Cons.DataFunctionId.HRV -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                dataBean.setLongData("hrv", data.toLong(4, 1))
                if (dataLength.toInt() == 0) return dataBean

                val dataList = mutableListOf<BaseDataBean>()
                val block = data.size.div(6)
                for (i in 0 until block) {
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.HRV,
                        data.toLong(i * 6 + 0, 4),
                        data.toLong(i * 6 + 4, 2).toInt()
                    )
                    dataList.add(bean)
                }
                dataBean.setBaseDataListData("hrv", dataList)
            }
//GPS
            Cons.DataFunctionId.GPS -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                //卫星数量
//                dataBean.setLongData("satelliteNumber", data.toLong(4, 1))
//                //经度 longitude
//                //(第5byte最高位作判断东经或西经，0:西经，1:东经)
//                //数据会保留6位小数，上报数据会扩大。
//                //例如:125.369874W,上报的数据会变成125369874
//                dataBean.setLongData("longitude", data.toLong(5, 4))
//                //纬度 latitude
//                // (第9byte最高位作判断东经或西经，0:南纬，1:北纬)
//                //数据会保留6位小数，上报数据会扩大。
//                //例如:75.369874S,上报的数据会变成75369874"
//                dataBean.setLongData("latitude", data.toLong(9, 5))
                if (dataLength.toInt() == 0) return dataBean

                val dataList = mutableListOf<GpsBean>()
                val block = data.size.div(14)
                for (i in 0 until block) {
                    val bean = GpsBean(
                        data.toLong(i * 14 + 0, 4),
                        data.toInt(i * 14 + 4, 1),
                        data.toLong(i * 14 + 5, 4),
                        data.toLong(i * 14 + 9, 5)
                    )
                    dataList.add(bean)
                }
                dataBean.setGpsListData("gps", dataList)
            }
            //车辆状态
            Cons.DataFunctionId.CAR_STATE -> {
                //时间戳
                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
                //车辆状态
                val carState = data[4]
                //门状态
                dataBean.setLongData("doorState", carState.getIndexToLong(0))
                //车窗状态
                dataBean.setLongData("windowState", carState.getIndexToLong(1))
                //发动机状态
                dataBean.setLongData("engineState", carState.getIndexToLong(2))
                //空调状态
                dataBean.setLongData("airState", carState.getIndexToLong(3))
                //后备箱状态
                dataBean.setLongData("backBoxState", carState.getIndexToLong(4))
                //燃油剩余量（0~99）百分比
                dataBean.setLongData("oilSurplus", data.toLong(5, 1))
                //高压电量剩余（0~99）百分比
                dataBean.setLongData("highVoltageResidual", data.toLong(6, 1))
                //低压电池电压
                dataBean.setLongData("LowVoltage", data.toLong(7, 1))
                //车速（km/h)
                dataBean.setLongData("speed", data.toLong(8, 1))
                //胎压（单位：0.1Bar)
                dataBean.setLongData("tirePressure", data.toLong(9, 4))
                //水温（℃）
                dataBean.setLongData("waterTemperature", data.toLong(13, 1))
                //"油耗（百公里/升） 转换成整数，油耗 * 10"
                dataBean.setLongData("oilWear", data.toLong(14, 1))
                //总公里数（km)
                dataBean.setLongData("totalMileage", data.toLong(15, 4))
                //保养里程(km)
                dataBean.setLongData("maintainMileage", data.toLong(19, 4))
                //故障码（保留）
                // dataBean.dataMap["errorCode",data.toLong(23,n )
            }
            //车辆控制 无此项，该项仅由APP发送
            Cons.DataFunctionId.CAR_CONTROL -> {}
            //心电 TODO
            Cons.DataFunctionId.ECG -> {
                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
                // 4~n 每四个字节为一组数据解析心电值
                val startIndex = 4
                val dataSize = (dataLength.toInt() - 4) / 4
                for (i in 0 until dataSize) {
                    val heart = data.toLong(startIndex + (i * 4), 4)
                    dataBean.setLongData("$i", heart)
                }
            }
            //RRI
            Cons.DataFunctionId.RRI -> {
                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
                dataBean.setLongData("rri", data.toLong(4, 4))
            }
            //大气压值
            Cons.DataFunctionId.BAROMETRIC_PRESSURE -> {
                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
                dataBean.setLongData("barometricPressure", data.toLong(4, 4))
            }
            //体温
            Cons.DataFunctionId.BODY_TEMPERATURE -> {
//                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
//                //"体温值（摄氏度） 转化成整数，体温值 * 10"
//                dataBean.setLongData("bodyTemperature", data.toLong(4, 2))
//                //"环境温度值（摄氏度） 转化成整数，体温值 * 10 bit15:1,代表负数；0，代表正数"
//                val environmentTemperature = (data[6].toLong() shl 8) or (data[7].toLong() and 0xFF)
//                dataBean.setLongData("environmentTemperature", environmentTemperature)

                val block = data.size.div(8)
                val temperatureList = mutableListOf<BaseDataBean>()
                for (i in 0 until block) {
                    val body = data.toLong(i * 8 + 4, 2)
                    val environment =
                        ((data[i * 8 + 6].toLong() shl 8) or (data[i * 8 + 7].toLong() and 0xFF)).toInt()
                    val bean = BaseDataBean(
                        Cons.DataFunctionId.BODY_TEMPERATURE,
                        data.toLong(i * 8 + 0, 4),
                        0
                    )
                    bean.arg1 = body.toString()
                    bean.arg2 = environment.toString()
                    temperatureList.add(bean)
                }
                dataBean.setBaseDataListData("temperature", temperatureList)
            }

            //车辆坐标范围
            Cons.DataFunctionId.CAR_COORDINATE_RANGE -> {}

            //跳绳数据
            Cons.DataFunctionId.JUMP_ROPE -> {

            }

            //Gsensor
            Cons.DataFunctionId.G_SENSOR -> {
                //时间戳
                dataBean.setLongData(Cons.Common.TIME_STAMP, data.toLong(0, 4))
                //步数
                dataBean.setLongData("stepData", data.toLong(4, 4))
                //卡路里（卡）
                dataBean.setLongData("calorie", data.toLong(8, 4))
                //距离（米）
                dataBean.setLongData("distance", data.toLong(12, 4))
            }
            //endregion

            //region 推送消息类型
            //音乐控制
            Cons.PushFunctionId.MUSIC_CONTROL -> {
                Log.d(TAG, "音乐控制，调整大小声")
                dataBean.setLongData("volume", data.toLong(0, 1))
            }
            //时间更新请求
            Cons.PushFunctionId.TIME_UPDATE -> {
                if (dataLength.toInt() == 0) {
                    //数据长度为0，请求时间更新
                    Log.d(TAG, "数据长度为0，请求时间更新 ")
                }
            }
            //endregion

            else -> {
                Log.d(TAG, "未找到解析数据ID: $functionId")
            }
        }

        return dataBean
    }


    /**
     * 组装数据
     * TODO 仅完成了当前帧、数据、数据长度的拼装，未完成数据包长度和校验和的改装
     */
    fun packageData(rawData: ByteArray): ByteArray? {

        val currFrame = rawData.toInt(
            Cons.ProtocolIndex.CURRENT_FRAME_INDEX,
            Cons.ProtocolIndex.CURRENT_FRAME_SIZE
        )
        val totalFrame =
            rawData.toInt(Cons.ProtocolIndex.TOTAL_FRAME_INDEX, Cons.ProtocolIndex.TOTAL_FRAME_SIZE)

        // 总帧数为1，说明是完整数据，直接发回去
        if (totalFrame == 1) return rawData

        val functionId = rawData.toUShort(
            Cons.ProtocolIndex.FUNCTION_ID_INDEX,
            Cons.ProtocolIndex.FUNCTION_ID_SIZE
        )
        val dataLength = rawData.toUShort(
            Cons.ProtocolIndex.DATA_LENGTH_INDEX,
            Cons.ProtocolIndex.DATA_LENGTH_SIZE
        )
        val data = copyFrom(rawData, Cons.ProtocolIndex.DATA_INDEX, dataLength)

        // 总帧数大于1，需要拼装
        if (currFrame == 1) {
            // 第一帧 将数据直接存入
            Log.d(TAG, "第一帧 ${ByteUtils.toHexString(rawData)}")
            functionMap[functionId] = rawData
            mFunctionHandler.sendEmptyMessageDelayed(
                functionId.toInt(),
                PACKAGE_DATA_TIME_OUT.toLong()
            )
            return null
        } else if (currFrame < totalFrame) {
            //中间帧 进行数据拼装
            //拿到之前本地的数据
            val tempData = functionMap[functionId]
            if (tempData == null) {
                //本地数据获取失败
                Log.d(TAG, "中间帧 缺少前一帧")
                mFunctionHandler.sendEmptyMessage(functionId.toInt())
            } else {
                //判断是否丢帧
                //本地存储的帧索引
                val tempFrame = tempData[Cons.ProtocolIndex.CURRENT_FRAME_INDEX]
                if (currFrame - tempFrame != 1) {
                    Log.d(TAG, "出现丢包  >> currFrame:$currFrame ::  tempFrame:$tempFrame")
                    mFunctionHandler.sendEmptyMessage(functionId.toInt())
                    return null
                }
                //更新帧索引
                tempData[Cons.ProtocolIndex.CURRENT_FRAME_INDEX] = currFrame.toByte()

                //计算新的数据包的数据长度(dataLength)
                val tempPackageLength = tempData.toUShort(
                    Cons.ProtocolIndex.DATA_LENGTH_INDEX,
                    Cons.ProtocolIndex.DATA_LENGTH_SIZE
                )
                val newPackageLength = tempPackageLength + dataLength
                val packageLength = ByteUtils.short2Bytes(newPackageLength.toShort())
                tempData[Cons.ProtocolIndex.DATA_LENGTH_INDEX] = packageLength[0]
                tempData[Cons.ProtocolIndex.DATA_LENGTH_INDEX + 1] = packageLength[1]

                //拼接数据
                val newResult = tempData.plus(data)
                //存入本地
                functionMap[functionId] = newResult
                Log.d(TAG, "中间帧: ${ByteUtils.toHexString(newResult)}")
            }
            //发送超时信息
            mFunctionHandler.removeMessages(functionId.toInt())
            mFunctionHandler.sendEmptyMessageDelayed(
                functionId.toInt(),
                PACKAGE_DATA_TIME_OUT.toLong()
            )
            return null
        } else {
            //当前帧==总帧数 最后一帧
            //拿到之前本地的数据
            val tempData = functionMap[functionId]
            return if (tempData == null) {
                //本地数据获取失败
                Log.d(TAG, "最后一帧 缺少前一帧")
                mFunctionHandler.sendEmptyMessage(functionId.toInt())
                null
            } else {
                mFunctionHandler.removeMessages(functionId.toInt())
                //计算新的数据包的数据长度(dataLength)
                val tempPackageLength = tempData.toUShort(
                    Cons.ProtocolIndex.DATA_LENGTH_INDEX,
                    Cons.ProtocolIndex.DATA_LENGTH_SIZE
                )
                val newPackageLength = tempPackageLength + dataLength
                val packageLength = ByteUtils.short2Bytes(newPackageLength.toShort())
                tempData[Cons.ProtocolIndex.DATA_LENGTH_INDEX] = packageLength[0]
                tempData[Cons.ProtocolIndex.DATA_LENGTH_INDEX + 1] = packageLength[1]
                //拼接数据
                val newResult = tempData.plus(data)
                //将本地数据清空
                functionMap.remove(functionId)
                Log.d(TAG, "最后一帧:  ${ByteUtils.toHexString(newResult)}")
                //返回拼装后的数据
                newResult
            }
        }

    }


    // --------------------------------------------------------------------------------------------
    private fun copyFrom(src: ByteArray, off: Int, len: UShort): ByteArray {
        // return Arrays.copyOfRange(src, off, off + len);
        val bits = ByteArray(len.toInt())
        var i = off
        var j = 0
        while (i < src.size && j < len.toInt()) {
            bits[j] = src[i]
            i++
            j++
        }
        return bits
    }


    //消息通知清单
    private fun getNotifyList(data: Byte): List<Int> {
        val list = mutableListOf<Int>()
        for (i in 0..7) {
            list.add(if (data.toInt() and (1 shl i) != 0) 1 else 0)
        }
        Log.d(TAG, "getNotifyList: $list")
        return list
    }

    private fun sendTask(
        id: Int,
        longMap: MutableMap<String, Long> = mutableMapOf<String, Long>(),
        stringMap: MutableMap<String, String> = mutableMapOf<String, String>()
    ) {
        val task = TaskEventBean(id, longMap, stringMap)
        LiveEventBus.get(Cons.LiveDataBus.DEVICE_TO_APP_TASK, TaskEventBean::class.java).post(task)

    }

    private fun sleepString(data: Int): String {
        return when (data) {
            0 -> "开始"
            1 -> "浅睡眠"
            2 -> "深睡眠"
            3 -> "快速眼动"
            4 -> "清醒"
            else -> "未知状态"
        }
    }
}